﻿// -----------------------------------------------------------------------
// <copyright file="PomodoroTimer.cs" company="">
// TODO: Update copyright text.
// </copyright>
// -----------------------------------------------------------------------

namespace Noc.Pomodoro.Controls
{
    using System;
    using System.Timers;
    using System.Windows;

    /// <summary>
    /// TODO: Update summary.
    /// </summary>
    public class PomodoroTimer : FrameworkElement
    {
        private readonly Timer clockTimer;

        /// <summary>
        /// Backing store for the <c>Time</c> property.
        /// </summary>
        public static DependencyProperty TimeProperty = DependencyProperty.Register("Time", typeof(TimeSpan), typeof(PomodoroTimer), new PropertyMetadata(new TimeSpan()));

        /// <summary>
        /// Backing store for the <c>Progress</c> property.
        /// </summary>
        public static DependencyProperty ProgressProperty = DependencyProperty.Register("Progress", typeof(double), typeof(PomodoroTimer), new PropertyMetadata(0.0));

        /// <summary>
        /// Backing store for the Delete event.
        /// </summary>
        public static readonly RoutedEvent FinishedEvent = EventManager.RegisterRoutedEvent("Finished", RoutingStrategy.Bubble, typeof(EventHandler<RoutedEventArgs>), typeof(PomodoroTimer));

        private DateTime enabledTime;

        private TimeSpan enabledDuration;

        /// <summary>
        /// Initializes a new instance of the <see cref="PomodoroTimer"/> class.
        /// </summary>
        public PomodoroTimer()
        {
            this.clockTimer = new Timer(150) { AutoReset = true, };
            this.clockTimer.Elapsed += new ElapsedEventHandler(this.OnTimerTicked);
        }

        /// <summary>
        /// Occurs when a pomodoro has been deleted from the task.
        /// </summary>
        public event EventHandler<RoutedEventArgs> Finished
        {
            add { AddHandler(FinishedEvent, value); }
            remove { RemoveHandler(FinishedEvent, value); }
        }

        public TimeSpan Time
        {
            get { return (TimeSpan)GetValue(TimeProperty); }
            set { SetValue(TimeProperty, value); }
        }

        public double Progress
        {
            get { return (double)GetValue(ProgressProperty); }
            set { SetValue(ProgressProperty, value); }
        }

        public void Start()
        {
            this.enabledTime = DateTime.Now;
            this.enabledDuration = this.Time;
            this.clockTimer.Enabled = true;
            this.Progress = 0.0;
        }

        public void Stop()
        {
            this.clockTimer.Enabled = false;
        }

        private void OnTimerTicked(object sender, ElapsedEventArgs e)
        {
            var remainingTime = this.enabledDuration.Subtract(DateTime.Now.Subtract(this.enabledTime));
            var completed = remainingTime.TotalSeconds / this.enabledDuration.TotalSeconds;
            if (remainingTime <= TimeSpan.Zero)
            {
                remainingTime = TimeSpan.Zero;
                this.Stop();
                Dispatcher.Invoke(new Action(() => { RaiseEvent(new RoutedEventArgs(FinishedEvent)); }));
            }

            Dispatcher.Invoke(new Action(() => this.Time = remainingTime));
            Dispatcher.Invoke(new Action(() => this.Progress = 1.0 - completed));
        }
    }
}